package tcc.wa.persistence.dao;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import tcc.wa.model.DailyWeatherForecast;
import tcc.wa.model.GeographicCoordinate;
import tcc.wa.model.Location;
import tcc.wa.persistence.dao.base.DAOBase;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

/**
 * Data access object class responsible for DailyWeatherForecast
 * persistence management.
 */
public class DailyWeatherForecastDAO extends DAOBase {

	private final String findLastDailyWeatherForecastString = 
			"SELECT * FROM " + FORECAST_TABLE_NAME + " f INNER JOIN " + DAILY_WEATHER_FORECAST_TABLE_NAME + " dwf ON dwf.forecast_id = f.id " +
					"INNER JOIN " + LOCATION_TABLE_NAME + " l ON f.location_id = l.id";
	
	public DailyWeatherForecastDAO(Context context) {
		super(context);
	}
	
	/**
	 * Saves a list of daily weather forecasts on the database.
	 *
	 * @param dailyForecasts the list to be saved
	 */
	public void save(List<DailyWeatherForecast> dailyForecasts) {
		clearPreviousForecasts();
		SQLiteDatabase database = getWritableDatabase();
		for (DailyWeatherForecast dailyForecast : dailyForecasts) {
			ContentValues forecastValues = new ContentValues();
			forecastValues.put("location_id", dailyForecast.getLocation().getId());
			forecastValues.put("date", dailyForecast.getDate().getTime());
			long forecastId = database.insert(FORECAST_TABLE_NAME, null, forecastValues);
			ContentValues dailyForecastValues = new ContentValues();
			dailyForecastValues.put("forecast_id", forecastId);
			dailyForecastValues.put("relative_humidity", dailyForecast.getRelativeHumidity());
			dailyForecastValues.put("precipitation", dailyForecast.getPrecipitation());
			dailyForecastValues.put("maximum_temperature", dailyForecast.getMaximumTemperature());
			dailyForecastValues.put("minimum_temperature", dailyForecast.getMinimumTemperature());
			long dailyForecastId = database.insert(DAILY_WEATHER_FORECAST_TABLE_NAME, null, dailyForecastValues);
			dailyForecast.setDailyWeatherForecastId(dailyForecastId);
			dailyForecast.setForecastId(forecastId);
		}
		close();
	}
	
	/**
	 * Finds the last daily weather forecasts saved.
	 *
	 * @return the last daily weather forecasts
	 */
	public List<DailyWeatherForecast> findLast() {
		List<DailyWeatherForecast> dailyForecasts = new ArrayList<DailyWeatherForecast>();
		SQLiteDatabase database = getWritableDatabase();
		Cursor cursor = database.rawQuery(findLastDailyWeatherForecastString, null);
		while (cursor.moveToNext()) {
			DailyWeatherForecast dailyForecast = new DailyWeatherForecast();
			dailyForecast.setForecastId(cursor.getLong(0));
			dailyForecast.setDate(new Date(cursor.getLong(1)));
			dailyForecast.setDailyWeatherForecastId(cursor.getLong(3));
			dailyForecast.setRelativeHumidity(cursor.getDouble(5));
			dailyForecast.setPrecipitation(cursor.getDouble(6));
			dailyForecast.setMaximumTemperature(cursor.getDouble(7));
			dailyForecast.setMinimumTemperature(cursor.getDouble(8));
			Location location = new Location();
			location.setId(cursor.getLong(9));
			location.setCity(cursor.getString(10));
			location.setState(cursor.getString(11));
			location.setRegion(cursor.getString(12));
			location.setCountry(cursor.getString(13));
			location.setGeographicCoordinate(new GeographicCoordinate(cursor.getDouble(14), cursor.getDouble(15)));
			dailyForecast.setLocation(location);
			dailyForecasts.add(dailyForecast);
		}
		close();
		return dailyForecasts;
	}
	
	/**
	 * Clear previous forecasts.
	 */
	private void clearPreviousForecasts() {
		SQLiteDatabase database = getWritableDatabase();
		List<Long> forecastIds = new ArrayList<Long>();
		Cursor cursor = database.query(DAILY_WEATHER_FORECAST_TABLE_NAME, new String[] { "forecast_id" }, null, null, null, null, null);
		while (cursor.moveToNext())
			forecastIds.add(cursor.getLong(0));
		database.delete(DAILY_WEATHER_FORECAST_TABLE_NAME, null, null);
		for (long forecastId : forecastIds)
			database.delete(FORECAST_TABLE_NAME, "id=?", new String[] { String.valueOf(forecastId) });
		close();
	}
}
